package com.study.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.fastjson.JSON;
import com.study.fall_handler.StudyFallbackHandler;
import com.study.vo.JwtToken;
import com.study.vo.UsernameAndPassword;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * sentinel 提供容错降级供功能
 */
@Slf4j
@RestController
@RequestMapping("/sentinel-fallback")
public class SentinelFallbackController {

    //这是普通的restTemplate
    private final RestTemplate restTemplate;

    public SentinelFallbackController(RestTemplate restTemplate){
        this.restTemplate = restTemplate;
    }

    @PostMapping("/get-token")
    @SentinelResource(
            value = "getTokenFromAuthorityService",
            fallback = "getTokenFromAuthorityServiceFallback",
            fallbackClass = StudyFallbackHandler.class
    )
    public JwtToken getTokenFromAuthorityService(
            @RequestBody UsernameAndPassword usernameAndPassword){

        String requestUrl =
                "http://127.0.0.1:7000/ecommerce-authority-center/authority/getToken";
        log.info("restTemplate request url and body: [{}],[{}]",
                requestUrl, JSON.toJSONString(usernameAndPassword));

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        return restTemplate.postForObject(
                requestUrl,
                new HttpEntity<>(JSON.toJSONString(usernameAndPassword),httpHeaders),
                JwtToken.class);
    }

    /**
     * Sentinel忽略异常：抛给统一处理异常
     * @param code
     * @return
     */
    @GetMapping("/ignore-exception")
    @SentinelResource(
            value = "ignoreException",
            fallback = "ignoreExceptionFallback",
            fallbackClass = {StudyFallbackHandler.class},
            exceptionsToIgnore = {NullPointerException.class}
    )
    public static JwtToken ignoreException(@RequestParam Integer code){

        if(code % 2 == 0){
            throw new NullPointerException("code is : " + code);
        }

        return new JwtToken("ignoreException-fallback");
    }

    public static JwtToken ignoreExceptionFallback(Integer code){

        log.error("code [{}] trigger exception",code);

        return new JwtToken("ignoreExceptionFallback");
    }

}
